<?php

declare ( strict_types = 1 )
	;

namespace Initiating\Client;

use Swoole\Client;
use Communication\TxSocketData;
use UntilDistributed\ConfigHelper;
use UntilDistributed\Constant;

/**
 * tcp 客户端
 * 
 * @author mg
 *        
 */
class TxClientManage {
	/**
	 *
	 * @var Client
	 */
	public $swooleClient;
	
	private const END_STRING = "\r\n\r\n";
	
	public function getSwooleClient(): Client
	{
		return $this->swooleClient;
	}
	
	/**
	 *
	 * @var array
	 */
	public $swClientConfig;
	public function __construct() {
		$config = ConfigHelper::get ( 'sw_client' );
		if (empty ( $config ['host'] )) {
			throw new \Exception ( "Error txmanage config", 1 );
		}
		$this->swClientConfig = $config;
		$this->swooleClient = new Client ( SWOOLE_TCP |SWOOLE_KEEP );
	}
	/**
	 * 链接服务端
	 * @param array $config
	 * @throws \Exception
	 * @return mixed
	 */
	public function connect(array $config = array()) {
		
		if ($this->swooleClient->isConnected()) {
			return true;
		}
		$this->swClientConfig = array_merge ( $this->swClientConfig, $config );
		
		$this->swooleClient->set ( array (
				'open_eof_check' => true,
				'package_eof' => static::END_STRING,
				'package_max_length' => 1024 * 1024 * 2 
		) );
		
		// 同步模式连接（是够考虑设置重试）
		$isconnected = $this->swooleClient->connect ( $this->swClientConfig ['host'], $this->swClientConfig ['port'], $this->swClientConfig ['timeout'], 0 );
		
		if (! $isconnected) {
			throw new \Exception ( "cannot connect txmanage server", 1 );
		}
		
		return $isconnected;
	}
	
	/**
	 * 发送数据与事务协调器通信(socket)
	 * 
	 * @return [type] [description]
	 */
	public function sendMsg($socketData) {
		$socketData->checkValid ();
		// 格式化消息
		$strMsg = serialize ( $socketData );
		$res = $this->swooleClient->send ( $strMsg . "\r\n\r\n" );
		return $res;
	}
	
	/**
	 * 回复成功
	 * 
	 * @return [type] [description]
	 */
	public function responseOk() {
		$socketData = new TxSocketData();
		$socketData->result = Constant::$socket_result_success;
		$strMsg = serialize ( $socketData );
		
		$res = $this->swooleClient->send ( $strMsg . "\r\n\r\n" );
		return $res;
	}
	
	/**
	 * 回复失败
	 * 
	 * @return [type] [description]
	 */
	public function responseFail() {
		$socketData = new TxSocketData ();
		$socketData->result = Constant::$socket_result_success;
		$strMsg = serialize ( $socketData );
		
		$res = $this->swooleClient->send ( $strMsg .static::END_STRING );
		return $res;
	}
	
	/**
	 * 接收消息
	 * 
	 * @return [type] [description]
	 */
	public function recv() : ? TxSocketData{
		$msg = $this->swooleClient->recv ();
		
		if (! $msg) {
			return null;
		}
		
		return TxSocketData::fromMsg ( $msg );
	}

	private function createTask()
	{
		$this->swooleClient->task;
	}
}